import { BadRequest, Unauthorized } from 'http-errors'
import bcrypt from 'bcryptjs'
import jwt from 'jsonwebtoken'
import { Op } from 'sequelize'
import User from '@/database/models/user'
import { queueProducer } from '@/utils/rabbit-mq'

const signUp = async (body: Body) => {
  // const body: Optional<InferCreationAttributes<User>, 'avatar' | 'id'>
  const user = await User.create({
    email: body.email,
    username: body.username,
    nickname: body.nickname,
    password: body.password,
    gender: 2,
    roleId: 1, // 写死 0:普通用户
  })
  const msg = {
    to: user.email,
    subject: '[大咪]注册成功通知',
    html: `
      您好，<span style="color: red">${user.nickname}。</span><br><br>
      恭喜，您已成功注册会员！<br><br>
      请访问<a href="http://localhost:5173/home">「大咪后台管理」</a>官网，了解更多。<br><br>
      ━━━━━━━━━━━━━━━━<br>
      大咪后台管理系统
    `,
  }
  await queueProducer(msg, 'mail_queue')
  return { ...user.dataValues, password: undefined }
}

const signIn = async (body: Body) => {
  const { login, password } = body
  if (!login) {
    throw new BadRequest('邮箱/用户名必须填写。')
  }
  if (!password) {
    throw new BadRequest('密码必须填写。')
  }
  let isLoginValid = true
  const user = await User.findOne({
    where: {
      [Op.or]: [{ email: login }, { username: login }],
    },
  })
  if (!user) {
    isLoginValid = false
  } else {
    const isPasswordValid = bcrypt.compareSync(password, user.password)
    isLoginValid = isPasswordValid
  }
  if (!isLoginValid) {
    throw new Unauthorized('用户名或密码错误。')
  }
  // 生成身份令牌
  const token = jwt.sign(
    {
      userId: user?.id,
    },
    process.env.SECRET as string,
    { expiresIn: '3d' },
  )
  return { token }
}

export default {
  signUp,
  signIn,
}
